package p200;

import javax.swing.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Stack;
import java.util.stream.Collectors;

/**
 * @author pengjz <br>
 * @version 1.0 <br>
 * @description Leetcode_224 <br>
 * @date 2021/3/10 22:41 <br>
 */
public class Leetcode_224 {

    public int calculate(String s) {
        s = s.replace(" ", "");
        if(s.startsWith("0")){
            s = "0" + s;
        }
        Stack<Character> stack = new Stack<>();
        List<String> list = new ArrayList<>();
        StringBuilder num = new StringBuilder();
        for (char c : s.toCharArray()) {
            if (Character.isDigit(c)) {
                // 数组要加上之前的数字
                num.append(c);
            } else {
                list.add(num.toString());
                num = new StringBuilder();
                // 如果是操作符
                if (stack.empty()) {
                    // 空栈直接入栈
                    stack.push(c);
                } else if (c == '(') {
                    // 左括号入栈
                    stack.push(c);
                } else if (c == ')') {
                    // 右括号，弹出操作符，直到遇到左括号
                    while (stack.peek() != '(') {
                        list.add(String.valueOf(stack.pop()));
                    }
                    // 把左括号弹出，不需要记录
                    stack.pop();
                } else {
                    // 如果是普通操作符，弹出所有优先级大于此运算符的运算符，栈可能弹空
                    while (!stack.empty() && getPriority(c) <= getPriority(stack.peek())) {
                        list.add(String.valueOf(stack.pop()));
                    }
                    // 当前运算符入栈
                    stack.push(c);
                }
            }
        }
        if (num.length() > 0) {
            list.add(num.toString());
        }
        // 弹出所有剩余元素
        while (!stack.empty()) {
            list.add(String.valueOf(stack.pop()));
        }
        List<String> collect = list.stream().filter(v -> v != null && v.length() > 0).collect(Collectors.toList());
        System.out.println(collect);
        // 然后对逆波兰表达式求值
        return evalRPN(collect.toArray(new String[]{}));
    }

    private int evalRPN(String[] tokens) {
        int[] ints = new int[tokens.length];
        int i = -1;
        for (String s : tokens) {
            switch (s) {
                case "+":
                    ints[--i] += ints[i + 1];
                    break;
                case "-":
                    ints[--i] -= ints[i + 1];
                    break;
                case "*":
                    ints[--i] *= ints[i + 1];
                    break;
                case "/":
                    ints[--i] /= ints[i + 1];
                    break;
                default:
                    ints[++i] = Integer.parseInt(s);
            }
        }
        return ints[i];
    }

    private int getPriority(Character op) {
        if (op == '*' || op == '/') {
            return 2;
        } else if (op == '+' || op == '-') {
            return 1;
        } else if (op == '(') {
            return 0;
        } else {
            return -1;
        }
    }

    public static void main(String[] args) {
        Leetcode_224 l = new Leetcode_224();
        System.out.println(l.calculate("1 + 1"));
    }
}
